package com.jwiki.app.jkeeper.interceptor;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.jwiki.app.jkeeper.common.data.Context;

public class SecurityInterceptor extends HandlerInterceptorAdapter {

    private String redirectUrl;

    private PathMatcher pathMatcher = new AntPathMatcher();

    private Set<String> ignoredUrlPatterns = new HashSet<String>(Arrays.asList("/**"));

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String url = request.getRequestURI().substring(request.getContextPath().length());
        for (String pattern : ignoredUrlPatterns) {
            if (pathMatcher.match(pattern, url)) {
                return true;
            }
        }

        if (request.getSession().getAttribute(Context.AUTH_INFO_KEY) == null) {
            if (request.getHeader("X-Requested-With") == null
                    || !request.getHeader("X-Requested-With").equalsIgnoreCase("XMLHttpRequest")) {
                // redirect
                response.sendRedirect(request.getContextPath() + redirectUrl);
            } else {
                // ajax
                response.setStatus(HttpStatus.FORBIDDEN.value());
            }
            return false;
        }

        return true;
    }

    public void setIgnoredUrlPatterns(Set<String> ignoredUrlPatterns) {
        Assert.notNull(ignoredUrlPatterns, "Ignored url patterns must not be null");
        this.ignoredUrlPatterns = ignoredUrlPatterns;
    }

    public void setRedirectUrl(String redirectUrl) {
        Assert.notNull(redirectUrl, "Redirect url must not be null");
        this.redirectUrl = redirectUrl;
    }

}
